﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Controls;
using System.IO;
using Hi_Baidu.User.Serializable.Log;
using System.Windows.Media.Imaging;
using Hi_Baidu.Enum.User;

namespace Hi_Baidu.ProcessModel
{
    /// <summary>
    ///     用户相关操作处理层
    /// </summary>
    class UserProcessModel : Model
    {
        private static String PackageBody;
        private static byte[] protocol;
        /// <summary>
        ///     服务器强制用户下线包处理
        /// </summary>
        public static void PROCESS_SET_OFFLINE()
        {
            if (Globle.win_Main != null)
            {
                ShowNotifyWindow("您被强制下线 !");
                //主面板关闭
                Globle.win_Main.Close();
            }
            Globle.win_Login.cmb_Username.Text = "";
            Globle.win_Login.password1.Password = "";
            //登陆面板开启
            Globle.win_Login.Show();
        }

        /// <summary>
        ///      更新用户上线状态
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="OnlineState">上线状态</param>
        public static void ChanageUserOnlineState(byte[] username, byte[] OnlineState)
        {
            if (username.Length > 0 && OnlineState.Length > 0)
            {
                byte[] UsernameLength = BitConverter.GetBytes(username.Length);
                byte[] IPAddress = Encoding.Default.GetBytes(Dns.GetHostAddresses(Dns.GetHostName())[0].ToString());
                byte[] IPLength = BitConverter.GetBytes(IPAddress.Length);
                byte[] TalkPort = BitConverter.GetBytes(Globle.user.TALK_PORT);
                byte[] None = new byte[2];
                byte[] PackageBody = new byte[username.Length + None.Length + IPAddress.Length + 16];
                Offset = 0;

                //用户名长度
                Array.ConstrainedCopy(UsernameLength, 0, PackageBody, Offset, UsernameLength.Length);
                Offset += 4;
                //用户名
                Array.ConstrainedCopy(username, 0, PackageBody, Offset, username.Length);
                Offset += username.Length;
                //上线状态
                Array.ConstrainedCopy(OnlineState, 0, PackageBody, Offset, OnlineState.Length);
                Offset += 4;
                //空白 
                Array.ConstrainedCopy(None, 0, PackageBody, Offset, None.Length);
                Offset += 2;
                //IP地址长度
                Array.ConstrainedCopy(IPLength, 0, PackageBody, Offset, IPLength.Length);
                Offset += 4;
                //IP地址
                Array.ConstrainedCopy(IPAddress, 0, PackageBody, Offset, IPAddress.Length);
                Offset += IPAddress.Length;
                //聊天端口
                Array.ConstrainedCopy(TalkPort, 0, PackageBody, Offset, TalkPort.Length);
                protocol = ProtocolFactory.ProtocolFactory.GetProtocol("GetMySelfInfo",
                                                                       (int)
                                                                       Packet.Protocol.OUT_NetworkCommand.
                                                                           CHANAGE_USER_ONLINE_STATE,
                                                                       (int) Packet.Protocol.NetworkProtocol.Base, PackageBody,
                                                                       ProtocolFactory.ProtocolFactory.ACK.Yes,
                                                                       ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                                                                       Globle.user.SESSION_CODE);
                //发送请求
                NetControl.Send(protocol, 8700, ServerIp);
            }
        }

        /// <summary>
        ///     向服务器发送指定用户心跳包
        /// </summary>
        /// <param name="username">用户名</param>
        public static void SendHeartBreath(byte[] username)
        {
            if (username.Length > 0)
            {
                byte[] UsernameLength = BitConverter.GetBytes(username.Length);
                byte[] IPAddress = Encoding.Default.GetBytes(Dns.GetHostAddresses(Dns.GetHostName())[0].ToString());
                byte[] IPLength = BitConverter.GetBytes(IPAddress.Length);
                byte[] TalkPort = BitConverter.GetBytes(Globle.user.TALK_PORT);
                byte[] None = new byte[2];
                byte[] OnlineState = BitConverter.GetBytes((int)Globle.user.USER_ONLINE_STATE);
                byte[] PackageBody = new byte[username.Length + None.Length + IPAddress.Length + 16];
                Offset = 0;
                //用户名长度
                Array.ConstrainedCopy(UsernameLength, 0, PackageBody, Offset, UsernameLength.Length);
                Offset += 4;
                //用户名
                Array.ConstrainedCopy(username, 0, PackageBody, Offset, username.Length);
                Offset += username.Length;
                //上线状态
                Array.ConstrainedCopy(OnlineState, 0, PackageBody, Offset, OnlineState.Length);
                Offset += 4;
                //空白 
                Array.ConstrainedCopy(None, 0, PackageBody, Offset, None.Length);
                Offset += 2;
                //IP地址长度
                Array.ConstrainedCopy(IPLength, 0, PackageBody, Offset, IPLength.Length);
                Offset += 4;
                //IP地址
                Array.ConstrainedCopy(IPAddress, 0, PackageBody, Offset, IPAddress.Length);
                Offset += IPAddress.Length;
                //聊天端口
                Array.ConstrainedCopy(TalkPort, 0, PackageBody, Offset, TalkPort.Length);
                protocol = ProtocolFactory.ProtocolFactory.GetProtocol("HeartBreath",
                                                                       (int)
                                                                       Packet.Protocol.OUT_NetworkCommand.HEART_BREATH_PACKAGE,
                                                                       (int)Packet.Protocol.NetworkProtocol.Base, PackageBody,
                                                                       ProtocolFactory.ProtocolFactory.ACK.Yes,
                                                                       ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                                                                       Globle.user.SESSION_CODE);
                //发送请求
                NetControl.Send(protocol, 8700, ServerIp);
            }
        }

        /// <summary>
        ///      还原用户原有上线状态
        /// </summary>
        public static void ReSetUserOnlineStateToOrg()
        {
            switch ((Hi_Baidu.Packet.InPacket.LoginReplyPacket.LoginState)int.Parse(Encoding.Default.GetString(Globle.user.DIC_USERINFO["LOGINLIVE"])))
            {
                case Hi_Baidu.Packet.InPacket.LoginReplyPacket.LoginState.Normal:
                    ((ComboBoxItem)Globle.win_Main.cb_OnlineState.Items[0]).IsSelected = true;
                    cls_Application_Init.SetNoityIconByUserState(ONLIN_STATE.ONLINE);
                    break;
                case Hi_Baidu.Packet.InPacket.LoginReplyPacket.LoginState.Hidden:
                    ((ComboBoxItem)Globle.win_Main.cb_OnlineState.Items[1]).IsSelected = true;
                    cls_Application_Init.SetNoityIconByUserState(ONLIN_STATE.HIDDEN);
                    break;
                case Hi_Baidu.Packet.InPacket.LoginReplyPacket.LoginState.Busy:
                    ((ComboBoxItem)Globle.win_Main.cb_OnlineState.Items[2]).IsSelected = true;
                    cls_Application_Init.SetNoityIconByUserState(ONLIN_STATE.BUSY);
                    break;
                case Hi_Baidu.Packet.InPacket.LoginReplyPacket.LoginState.Away:
                    ((ComboBoxItem)Globle.win_Main.cb_OnlineState.Items[3]).IsSelected = true;
                    cls_Application_Init.SetNoityIconByUserState(ONLIN_STATE.AWAY);
                    break;
            }
            ShowNotifyWindow("修改在线状态失败 !");
        }

        /// <summary>
        ///     保存当前登录状态到本机储存
        /// </summary>
        public static void SetUserOnlineState()
        {
            //更改本地状态存储器
            Globle.user.DIC_USERINFO["LOGINLIVE"] =
                Encoding.Default.GetBytes(
                    (Globle.win_Main.cb_OnlineState.SelectedItem as ComboBoxItem).Tag.ToString());
        }

        /// <summary>
        ///     显示提示窗口
        /// </summary>
        /// <param name="NotifyText" type="string">
        ///     <para>
        ///         提示信息
        ///     </para>
        /// </param>
        private static void ShowNotifyWindow(String NotifyText)
        {
            LoginProcessModel.ChangeState(false, Globle.win_Login);
            Win_Notify WN = new Win_Notify();
            WN.Owner = Globle.win_Login;
            WN.tb_Notify.Text = NotifyText;
            WN.ShowDialog();
        }

        /// <summary>
        ///     检测当前选定用户个人数据文件夹是否存在
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回false , 标表不存在
        /// </returns>
        public static bool CheckUserInfoRootExists(String username)
        {
            if(!Directory.Exists("../Users/" + username + "/"))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        ///     检测当前选定用户个人数据文件是否存在
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回false , 标表不存在
        /// </returns>
        public static bool CheckUserInfoFileExists(String username)
        {
            if (!File.Exists("../Users/" + username + "/Info.db"))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        ///     检测当前选定用户聊天记录文件是否存在
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回false , 标表不存在
        /// </returns>
        public static bool CheckUserTalkLogFileExists(String username)
        {
            if (!File.Exists("../Users/" + username + "/Msg1.0.db"))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        ///     检测当前选定用户好友备注文件是否存在
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回false , 标表不存在
        /// </returns>
        public static bool CheckUserMarkFileExists(String username)
        {
            if (!File.Exists("../Users/" + username + "/UserMark.db"))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        ///     创建个人信息完整存储空间
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void CreateProsernalInfomation(String username)
        {
        }

        /// <summary>
        ///     创建用户个人信息数据存储文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void CreateUserInfoDB(String username)
        {
            if (Globle.TEMP_USER_SETTING != null && Globle.TEMP_USER_SETTING.Username == username)
            {
                Globle.TEMP_USER_SETTING.Save(Globle.TEMP_USER_SETTING.FileName);
            }
            else
            {

                UserSettingInfo userSettingInfo = new UserSettingInfo("../Users/" + username + "/Info.db", "USER_SETTING_INFO");
                userSettingInfo.Username = username;
                userSettingInfo.Version = "1.0.0.0";
                Globle.userSettingInfo = userSettingInfo;
                userSettingInfo.Save("../Users/" + username + "/Info.db");
            }
        }

        /// <summary>
        ///     读取用户个人信息数据文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void ReadUserInfoDB(String username)
        {
            using (FileStream FS = new FileStream("../Users/" + username + "/Info.db", FileMode.Open))
            {
                using (MemoryStream MS = new MemoryStream())
                {
                    BinaryReader BR = new BinaryReader(FS);
                    byte[] EncryptData = BR.ReadBytes((int)FS.Length);
                    MS.Write(EncryptData, 0, EncryptData.Length);
                    MS.Position = 0;
                    UserSettingInfo userSettingInfo = new UserSettingInfo(MS, "USER_SETTING_INFO");
                    Globle.userSettingInfo = (UserSettingInfo)userSettingInfo.DeEncryptStream;
                }

                //开始判断
                Globle.win_Login.ckb_AutoLogin.IsChecked = Globle.userSettingInfo.AutoLogin;
                Globle.win_Login.ckb_RememberPassword.IsChecked = Globle.userSettingInfo.RememberPassword;
                Globle.win_Login.password1.Password = Globle.userSettingInfo.RememberPassword ? Globle.userSettingInfo.Password : "";
                Globle.win_Login.cb_OnlineState.SelectedIndex = Globle.userSettingInfo.LoginState;
                if (Globle.userSettingInfo.HeadImage != "")
                {
                    Globle.win_Login.img_User.Source = new BitmapImage(new Uri("../syshead/" + Globle.userSettingInfo.HeadImage + "_s.jpg", UriKind.RelativeOrAbsolute));
                }
                else
                {
                    Globle.win_Login.img_User.Source = new BitmapImage(new Uri("../syshead/02187B7BAF5C4FA270FDD856F80D9A10_s.png", UriKind.RelativeOrAbsolute));
                }
            }
        }

        /// <summary>
        ///     更新指定用户个人信息数据文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        public static void UpdateUserInfoDB(String username)
        {
            if (Globle.TEMP_USER_SETTING != null && Globle.TEMP_USER_SETTING.Username == username)
            {
                Globle.TEMP_USER_SETTING.Save(Globle.TEMP_USER_SETTING.FileName);
            }
        }

        /// <summary>
        ///     创建用户聊天记录数据存储文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void CreateUserMsgDB(String username)
        {
            UserTalkMessageLogManager userTalkMessageLogManager = new UserTalkMessageLogManager("../Users/" + username + "/Msg1.0.db", "USER_TALKINFO_LOG");
            userTalkMessageLogManager.Version = "1.0.0.0";
            Globle.userTalkMessageLogManager = userTalkMessageLogManager;
            userTalkMessageLogManager.Save("../Users/" + username + "/Msg1.0.db");
        }

        /// <summary>
        ///     读取用户个人聊天记录数据文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void ReadUserMsgDB(String username)
        {
            using (FileStream FS = new FileStream("../Users/" + username + "/Msg1.0.db", FileMode.Open))
            {
                using (MemoryStream MS = new MemoryStream())
                {
                    BinaryReader BR = new BinaryReader(FS);
                    byte[] EncryptData = BR.ReadBytes((int)FS.Length);
                    MS.Write(EncryptData, 0, EncryptData.Length);
                    MS.Position = 0;
                    UserTalkMessageLogManager userTalkMessageLogManager = new UserTalkMessageLogManager(MS, "USER_TALKINFO_LOG");
                    Globle.userTalkMessageLogManager = (UserTalkMessageLogManager)userTalkMessageLogManager.DeEncryptStream;
                }
            }
        }

        /// <summary>
        ///     创建用户好友备注数据存储文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void CreateUserMarkDB(String username)
        {
            UserMarkManager userMarkManager = new UserMarkManager("../Users/" + username + "/UserMark.db", "USER_FRIEND_MARK");
            userMarkManager.Version = "1.0.0.0";
            Globle.userMarkManager = userMarkManager;
            userMarkManager.Save("../Users/" + username + "/UserMark.db");
        }

        /// <summary>
        ///     读取用户好友备注数据文件
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void ReadUserMarkDB(String username)
        {
            using (FileStream FS = new FileStream("../Users/" + username + "/UserMark.db", FileMode.Open))
            {
                using (MemoryStream MS = new MemoryStream())
                {
                    BinaryReader BR = new BinaryReader(FS);
                    byte[] EncryptData = BR.ReadBytes((int)FS.Length);
                    MS.Write(EncryptData, 0, EncryptData.Length);
                    MS.Position = 0;
                    UserMarkManager userMarkManager = new UserMarkManager(MS, "USER_FRIEND_MARK");
                    Globle.userMarkManager = (UserMarkManager)userMarkManager.DeEncryptStream;
                }
            }
        }

        /// <summary>
        ///     创建用户目录下相关的文件夹
        /// </summary>
        /// <param name="username" type="string">
        ///     <para>
        ///         用户名
        ///     </para>
        /// </param>
        public static void CreateReferenceFolders(String username)
        {
            String ReferenceFolderPath = "../Users/" + username + "/";
            if(!Directory.Exists(ReferenceFolderPath + "RevImage" + "/"))
            {
                Directory.CreateDirectory(ReferenceFolderPath + "RevImage" + "/");
            }
            if (!Directory.Exists(ReferenceFolderPath + "FileRecv" + "/"))
            {
                Directory.CreateDirectory(ReferenceFolderPath + "FileRecv" + "/");
            }
        }

        public static void ProcessUserReference(Window1 Win_Login,String username)
        {
            //不存在用户个人文件夹
            if(!CheckUserInfoRootExists(username))
            {
                //建立
                Directory.CreateDirectory("../Users/" + username + "/");
            }
            //不存在用户个人数据文件
            if (!CheckUserInfoFileExists(username))
            {
                //建立
                CreateUserInfoDB(username);
            }
            //存在，则读取
            else
            {
                ReadUserInfoDB(username);
            }
            //不存在用户聊天记录文件
            if (!CheckUserTalkLogFileExists(username))
            {
                //建立
                CreateUserMsgDB(username);
            }
            //存在，则读取
            else
            {
                ReadUserMsgDB(username);
            }
            //不存在用户好友备注文件
            if (!CheckUserMarkFileExists(username))
            {
                //建立
                CreateUserMarkDB(username);
            }
            //存在，则读取
            else
            {
                ReadUserMarkDB(username);
            }
            CreateReferenceFolders(username);
        }
    }
}
